﻿// Decompiled with JetBrains decompiler
// Type: MCM.Implementation.BaseSettingsContainer`1
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using BUTR.DependencyInjection;
using MCM.Abstractions;
using MCM.Abstractions.Base;
using MCM.Abstractions.GameFeatures;
using System;
using System.Collections.Generic;
using System.Linq;

#nullable enable
namespace MCM.Implementation
{
  public abstract class BaseSettingsContainer<TSettings> : 
    ISettingsContainer,
    ISettingsContainerHasSettingsDefinitions,
    ISettingsContainerCanOverride,
    ISettingsContainerCanReset,
    ISettingsContainerPresets,
    ISettingsContainerHasSettingsPack
    where TSettings : BaseSettings
  {
    protected virtual GameDirectory RootFolder { get; }

    protected virtual Dictionary<string, TSettings> LoadedSettings { get; }

    public virtual IEnumerable<SettingsDefinition> SettingsDefinitions
    {
      get
      {
        return this.LoadedSettings.Values.Select<TSettings, SettingsDefinition>((Func<TSettings, SettingsDefinition>) (s => new SettingsDefinition(s.Id, s.DisplayName, s.GetSettingPropertyGroups())));
      }
    }

    protected virtual void RegisterSettings(TSettings? settings)
    {
      if ((object) settings == null || this.LoadedSettings.ContainsKey(settings.Id))
        return;
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return;
      this.LoadedSettings.Add(settings.Id, settings);
      GameDirectory directory1 = service.GetOrCreateDirectory(this.RootFolder, settings.FolderName);
      GameDirectory directory2 = string.IsNullOrEmpty(settings.SubFolder) ? directory1 : service.GetOrCreateDirectory(directory1, settings.SubFolder);
      ((IEnumerable<ISettingsFormat>) ((object) GenericServiceProvider.GetService<IEnumerable<ISettingsFormat>>() ?? (object) Array.Empty<ISettingsFormat>())).FirstOrDefault<ISettingsFormat>((Func<ISettingsFormat, bool>) (x => x.FormatTypes.Any<string>((Func<string, bool>) (y => y == settings.FormatType))))?.Load((BaseSettings) settings, directory2, settings.Id);
      settings.OnPropertyChanged("LOADING_COMPLETE");
    }

    public virtual BaseSettings? GetSettings(string id)
    {
      TSettings settings;
      return (BaseSettings) (this.LoadedSettings.TryGetValue(id, out settings) ? settings : default (TSettings));
    }

    public virtual bool SaveSettings(BaseSettings settings)
    {
      if (!(settings is TSettings) || !this.LoadedSettings.ContainsKey(settings.Id))
        return false;
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return false;
      GameDirectory directory1 = service.GetOrCreateDirectory(this.RootFolder, settings.FolderName);
      GameDirectory directory2 = string.IsNullOrEmpty(settings.SubFolder) ? directory1 : service.GetOrCreateDirectory(directory1, settings.SubFolder);
      ((IEnumerable<ISettingsFormat>) ((object) GenericServiceProvider.GetService<IEnumerable<ISettingsFormat>>() ?? (object) Array.Empty<ISettingsFormat>())).FirstOrDefault<ISettingsFormat>((Func<ISettingsFormat, bool>) (x => x.FormatTypes.Any<string>((Func<string, bool>) (y => y == settings.FormatType))))?.Save(settings, directory2, settings.Id);
      settings.OnPropertyChanged("SAVE_TRIGGERED");
      return true;
    }

    public virtual bool OverrideSettings(BaseSettings settings)
    {
      if (!(settings is TSettings) || !this.LoadedSettings.ContainsKey(settings.Id))
        return false;
      SettingsUtils.OverrideSettings((BaseSettings) this.LoadedSettings[settings.Id], settings);
      return true;
    }

    public virtual bool ResetSettings(BaseSettings settings)
    {
      if (!(settings is TSettings) || !this.LoadedSettings.ContainsKey(settings.Id))
        return false;
      SettingsUtils.ResetSettings((BaseSettings) this.LoadedSettings[settings.Id]);
      return true;
    }

    public IEnumerable<ISettingsPreset> GetPresets(string settingsId)
    {
      TSettings settings;
      if (this.LoadedSettings.TryGetValue(settingsId, out settings))
      {
        IFileSystemProvider fileSystemProvider = GenericServiceProvider.GetService<IFileSystemProvider>();
        if (fileSystemProvider != null)
        {
          GameDirectory presetsDirectory = fileSystemProvider.GetOrCreateDirectory(fileSystemProvider.GetModSettingsDirectory(), "Presets");
          GameDirectory settingsDirectory = fileSystemProvider.GetOrCreateDirectory(presetsDirectory, settingsId);
          GameFile[] gameFileArray = fileSystemProvider.GetFiles(settingsDirectory, "*.json");
          for (int index = 0; index < gameFileArray.Length; ++index)
          {
            GameFile filePath = gameFileArray[index];
            JsonSettingsPreset preset = JsonSettingsPreset.FromFile((BaseSettings) settings, filePath);
            if (preset != null)
              yield return (ISettingsPreset) preset;
            preset = (JsonSettingsPreset) null;
            filePath = (GameFile) null;
          }
          gameFileArray = (GameFile[]) null;
        }
      }
    }

    public bool SavePresets(ISettingsPreset preset)
    {
      TSettings settings;
      return this.LoadedSettings.TryGetValue(preset.SettingsId, out settings) && preset.SavePreset((BaseSettings) settings);
    }

    public IEnumerable<SettingSnapshot> SaveAvailableSnapshots()
    {
      JsonSettingsFormat jsonFormat = GenericServiceProvider.GetService<JsonSettingsFormat>();
      if (jsonFormat != null)
      {
        foreach (TSettings settings in this.LoadedSettings.Values)
        {
          TSettings setting = settings;
          string json = jsonFormat.SaveJson((BaseSettings) setting);
          string folderName = !string.IsNullOrEmpty(setting.FolderName) ? setting.FolderName + "/" : string.Empty;
          string subFolderName = !string.IsNullOrEmpty(setting.SubFolder) ? setting.SubFolder + "/" : string.Empty;
          string path = folderName + subFolderName + setting.Id + ".json";
          yield return new SettingSnapshot(path, json);
          json = (string) null;
          folderName = (string) null;
          subFolderName = (string) null;
          path = (string) null;
          setting = default (TSettings);
        }
      }
    }

    public IEnumerable<BaseSettings> LoadAvailableSnapshots(IEnumerable<SettingSnapshot> snapshots)
    {
      JsonSettingsFormat jsonFormat = GenericServiceProvider.GetService<JsonSettingsFormat>();
      if (jsonFormat != null)
      {
        Dictionary<string, string> snapshotDict = snapshots.ToDictionary<SettingSnapshot, string, string>((Func<SettingSnapshot, string>) (x => x.Path), (Func<SettingSnapshot, string>) (x => x.JsonContent));
        foreach (TSettings settings in this.LoadedSettings.Values)
        {
          TSettings setting = settings;
          string folderName = !string.IsNullOrEmpty(setting.FolderName) ? setting.FolderName + "/" : string.Empty;
          string subFolderName = !string.IsNullOrEmpty(setting.SubFolder) ? setting.SubFolder + "/" : string.Empty;
          string path = folderName + subFolderName + setting.Id + ".json";
          string json;
          if (snapshotDict.TryGetValue(path, out json))
            yield return jsonFormat.LoadFromJson(setting.CreateNew(), json);
          folderName = (string) null;
          subFolderName = (string) null;
          path = (string) null;
          json = (string) null;
          setting = default (TSettings);
        }
      }
    }

    protected BaseSettingsContainer()
    {
      GameDirectory gameDirectory = GenericServiceProvider.GetService<IFileSystemProvider>()?.GetModSettingsDirectory();
      if ((object) gameDirectory == null)
        gameDirectory = new GameDirectory(PlatformDirectoryType.User, "Configs\\ModSettings\\");
      this.RootFolder = gameDirectory;
      this.LoadedSettings = new Dictionary<string, TSettings>();
      // ISSUE: explicit constructor call
      base.\u002Ector();
    }
  }
}
